﻿using System;


namespace advadev.CanOpen
{

    /// <summary>
    /// Abstract base class of all services
    /// </summary>
    abstract public class ServiceBase : IService
    {

        /// <summary>
        /// Initializes a new instance of the ServiceBase class by the given
        /// parameter
        /// </summary>
        /// <param name="objectDictionaryContainer">
        /// Object dictionary container (must not be null)
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// Will be thrown if the object dictionary container is null
        /// </exception>
        protected ServiceBase(ICanOpenObjectDictionaryContainer objectDictionaryContainer)
        {
            // check parameter
            if (objectDictionaryContainer == null)
            {
                throw new ArgumentNullException("objectDictionaryContainer");
            }

            // initialization
            State = ServiceState.Stopped;
            ObjectDictionaryContainer = objectDictionaryContainer;
        }


        /// <summary>
        /// Gets the object dictionary container
        /// </summary>
        protected ICanOpenObjectDictionaryContainer ObjectDictionaryContainer
        {
            get;
            private set;
        }


        /// <summary>
        /// Requests the execution of the given transfer
        /// </summary>
        /// <param name="transfer">
        /// Transfer
        /// </param>
        protected void RequestTransfer(ITransfer transfer)
        {
            onRaiseTransferRequired(new ServiceTransferRequiredEventArgs(transfer));
        }

        /// <summary>
        /// Raises the transfer required event
        /// </summary>
        /// <param name="args">
        /// Event argument
        /// </param>
        private void onRaiseTransferRequired(ServiceTransferRequiredEventArgs args)
        {
            if (_transferRequired != null)
            {
                _transferRequired(this, args);
            }
        }


        #region IService implementation
        /// <summary>for internal use</summary>
        private event ServiceTransferRequiredEventHandler _transferRequired;

        /// <summary>
        /// Occures when a transfer is required
        /// </summary>
        public event ServiceTransferRequiredEventHandler TransferRequired
        {
            add
            {
                _transferRequired += value;
            }
            remove
            {
                _transferRequired -= value;
            }
        }

        /// <summary>
        /// Gets the service state
        /// </summary>
        public ServiceState State
        {
            get;
            protected set;
        }

        /// <summary>
        /// When implemented, starts the (stopped) service
        /// </summary>
        abstract public void Start();

        /// <summary>
        /// When implemented, pauses the (started) service
        /// </summary>
        abstract public void Pause();

        /// <summary>
        /// When implemented, resumes the (paused) service
        /// </summary>
        abstract public void Resume();

        /// <summary>
        /// When implemented, stops the (started or paused) service
        /// </summary>
        abstract public void Stop();
        #endregion IService implementation

    }

}
